local japi = require 'jass.japi'

--[[
    例子:手电筒照青蛙
    1.手电筒的灯泡就是镜头源
    2.照亮的区域就是镜头目标
    3.通过调整模型第一人称的x,y,让模型处在镜头目标的正中央

    ps:注意需要提前创建一个黑色背景的模型来强制渲染模型
]]


local model2 = {}
setmetatable(model2, model2)

--- 存放所有的模型II
model2.allmodels = {}

-- 存放模型的动画数据
model2.allanimations = {}


local mt = extends(class.model){}

--- 控件类型
mt.type = 'model2'

--- 识别名
mt._name = '大头像'

--- 模型路径
mt.model = [[UI\Glues\MainMenu\WarCraftIIILogo\WarCraftIIILogo.mdl]]

--- 队伍颜色 (0 - 15)
mt.color_id = 0

--- 模型镜头源位置 {x,y,z}
mt.source_point = nil 

--- 模型镜头目标位置 {x,y,z} 
mt.target_point = nil

--- 模型相对场景的坐标 {x,y,z}
mt.object_point = nil

--- 创建控件
function mt.new(parent, model,x,y, w, h)
    return class.model2:builder
    {
        parent = parent,
        model = model,
        x = x,
        y = y,
        w = w,
        h = h,
    }
end 

--- 输出
function mt:__tostring()
    return string.format('[模型2]->%d',self.handle or 0)
end


--- 初始化
function mt:init()
    if self.handle then return end 

    local handle = japi.FrameAddModel(self.parent.handle)
    if handle == nil or handle == 0 then 
        ac.frame.remove(self)
        log.error('创建model2失败')
        return
    end 
    self.handle = handle
    model2.allmodels[handle] = self
    ac.frame.allframes[handle] = self
    self:set_model(self.model, self.color_id)
    self:reset()
    if self.show_flag then
        self.show_flag = false
        self:show()
    else 
        self.show_flag = true
        self:hide()
    end
    return self
end 

--- 删除控件
function mt:remove()
    if self.removed then return end
    if self:is_simple() then return end
    self:flush_attach()
    model2.allmodels[self.handle] = nil
    ac.frame.remove(self)
end

--- 重新设置 通常来说修改模型后 也要修改参数 直接重新设置
function mt:reset()
    self:replace_textures(self.textures)
    self:set_size(self.size)
    self:set_color(self.color)
    self:set_speed(self.speed)
    self:set_offset(self.offset_x,self.offset_y)
    self:set_scales(self.scales)
    self:set_rotates(self.rotates)
    self:set_camera_source(self.source_point)
    self:set_camera_target(self.target_point)
    self:set_object_point(self.object_point)
    self:set_alpha(self.alpha)
    self:set_width(self.w)
    self:set_height(self.h)
    self:set_position(self.x,self.y)
    self:set_ignore_trackevents(self.ignore_flag)
    if type(self.animation) == 'string' then 
        self:play_animation_by_name(self.animation)
    else 
        self:play_animation(self.animation, self.is_loop)
    end 
end

--- 设置模型 颜色id 是 0~15 = 玩家颜色
function mt:set_model(model, color_id)
    self.model = model 
    self.color_id = color_id
    if self.removed then return end
    self:flush_attach()
    japi.FrameSetModel2(self.handle, self.model, self.color_id)
    local modelname = self.model:lower():gsub('.mdl', '.mdx')
    if not model2.allanimations[modelname] then 
        local animations = {}
        local count = japi.FrameGetModelAnimationCount(self.handle)
        if count > 0 then
            for i = 0, count - 1 do
                local name = string.lower(japi.FrameGetModelAnimationName(self.handle, i))
                animations[name] = i
                animations[i] = name
            end
        end
        model2.allanimations[modelname] = animations
    end
    self._animationdata = model2.allanimations[modelname]
end

--- 播放模型动画
function mt:play_animation_by_name(name)
    self:set_animation_by_index(self._animationdata[string.lower(name)] or 0)
end 

--- 遍历模型动画表
function mt:search_animations()
    local i = -1
    return function()
        i = i + 1
        return self._animationdata[i], i 
    end
end

--- 设置镜头源位置  
function mt:set_camera_source(source_point)
    if self.removed then return end
    if type(source_point) ~= 'table' then return end
    local x,y,z = table.unpack(source_point)
    japi.FrameSetModelCameraSource(self.handle, x or 0, y or 0, z or 0)
end

--- 设置镜头目标位置
function mt:set_camera_target(target_point)
    if self.removed then return end
    if type(target_point) ~= 'table' then return end
    local x,y,z = table.unpack(target_point)
    japi.FrameSetModelCameraTarget(self.handle,x or 0, y or 0, z or 0)
end

--- 设置模型相对场景的坐标
function mt:set_object_point(object_point)
    if self.removed then return end
    if type(object_point) ~= 'table' then return end
    local x,y,z = table.unpack(object_point)
    japi.FrameSetModelX(self.handle, x or 0)
    japi.FrameSetModelY(self.handle, y or 0)
    japi.FrameSetModelZ(self.handle, z or 0)
end

--- 获取模型场景内的位置
function mt:get_object_point()
    return japi.FrameGetModelX(self.handle), japi.FrameGetModelY(self.handle),0
end

--- 添加绑点特效 
--- @return effect 模型地址
function mt:add_effect(model, socket)
    if self.removed then return end
    local effect = japi.FrameAddModelEffect(self.handle, socket or "origin", model)
    self.attach[effect] = true
    return effect
end

--- 删除绑点特效 需要填 绑特效时的返回值
function mt:remove_effect(effect)
    if self.attach[effect] then 
        self.attach[effect] = nil
        japi.FrameRemoveModelEffect(self.handle, effect)
    end
end

--- 删除所有绑定 特效
function mt:flush_attach()
    if self.removed then return end
    local attach = self.attach
    self.attach = { }
    if not attach then return end 
    for effect in pairs(attach) do 
        japi.FrameRemoveModelEffect(self.handle, effect)
    end 
end

class.model2 = mt

return mt